<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>FLIP 动画</title>
  <style>
    #list {
      margin: 0 auto;
      width: 500px;
      display: flex;
      flex-wrap: wrap;
    }
    .item {
      width: 100px;
      height: 100px;
      background-color: #004ff8;
      box-sizing: border-box;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 40px;
      color: #FFF;
      border: 1px solid #FFF;
    }
    .item:nth-child(2n) {
      background-color: #69B1FF;
    }
    #modal {
      position: fixed;
      width: 100%;
      height: 100%;
      background-color: rgba(0, 0, 0, 0.3);
      top: 0;
      left: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      transition-timing-function: ease-out;
    }
    #modal .item {
      width: 100%;
      height: 300px;
    }
  </style>
</head>
<body>
  <div id="list">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
  </div>
<!--  <div id="modal">-->
<!--    <div class="item">demo</div>-->
<!--  </div>-->
</body>
<script>
const list = document.getElementById('list')
const sortBtn = document.getElementById('sort')
let modal
let current

const all = [...list.children]
// 记录开始位置信息
all.forEach((item, i) => {
  const rect = item.getBoundingClientRect()
  item.startX = rect.left
  item.startY = rect.top
  item.width = rect.width
  item.height = rect.height
})

function play(preItem) {
  modal.animate([
    {backgroundColor: `rgba(0, 0, 0, 0)`},
    {backgroundColor: `rgba(0, 0, 0, ${0.3})`}
  ], {duration: 600})

  const rect = current.getBoundingClientRect()
  const currentX = rect.left
  const currentY = rect.top
  const width = rect.width
  const height = rect.height

  const x = preItem.startX - currentX - (width - preItem.width) / 2
  const y = preItem.startY - currentY - (height - preItem.height) / 2

  console.log(x, y)

  current.animate([
    {
      transform: `translate(${x}px, ${y}px)`,
      width: `${preItem.width}px`,
      height: `${preItem.height}px`
    },
    {
      transform: 'translate(0px, 0px)',
      height: `${height}px`,
      width: `${width}px`
    }
  ], {duration: 600})
}

function change(element) {
  current = element.cloneNode(true)
  modal = document.createElement('div')

  modal.id = 'modal'
  modal.appendChild(current)
  document.body.appendChild(modal)

  modal.onclick = () => {
    const ani = modal.animate([
      {backgroundColor: `rgba(0, 0, 0, ${0.3})`},
      {backgroundColor: `rgba(0, 0, 0, 0)`}
    ], {duration: 600})

    const rect = current.getBoundingClientRect()
    const currentX = rect.left
    const currentY = rect.top
    const width = rect.width
    const height = rect.height

    const x = element.startX - currentX - (width - element.width) / 2
    const y = element.startY - currentY - 100

    current.animate([
      {
        transform: 'translate(0px, 0px)',
        height: `${height}px`,
        width: `${width}px`
      },
      {
        transform: `translate(${x}px, ${y}px)`,
        width: `${element.width}px`,
        height: `${element.height}px`
      },
    ], {duration: 600})

    console.log(x, y)

    ani.onfinish = () => {
      modal.remove()
    }
  }
}

all.forEach((item, i) => {
  item.onclick = (event) => {
    change(event.target)
    play(event.target, i)
  }
})

</script>
</html>
